package cn.heyige.backend.facade;

import cn.heyige.backend.config.AppConfig;
import cn.heyige.backend.dto.EmailDto;
import cn.heyige.backend.service.ai.AiModelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * API KEY监控服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ApiKeyMonitorFacade {
    
    private final List<AiModelService> modelServices;
    private final EmailFacade emailFacade;
    private final AppConfig appConfig;
    
    // 存储上次检查状态的缓存
    private final Map<String, Boolean> lastStatusCache = new HashMap<>();
    
    // 存储异常次数的计数器
    private final Map<String, Integer> errorCountMap = new HashMap<>();
    
    // 异常阈值，超过此次数才发送邮件
    private static final int ERROR_THRESHOLD = 3;
    
    /**
     * 定时检查API KEY状态（每5分钟执行一次）
     */
    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void checkApiKeyStatus() {
        log.info("开始检查API KEY状态");
        
        for (AiModelService service : modelServices) {
            String serviceName = service.getModelName();
            boolean currentStatus = checkServiceStatus(service);
            
            // 获取上次状态
            Boolean lastStatus = lastStatusCache.get(serviceName);
            
            // 状态变化处理
            if (lastStatus != null && lastStatus != currentStatus) {
                if (!currentStatus) {
                    // 服务从正常变为异常
                    handleServiceError(serviceName, "服务连接失败", "AI服务无法连接，请检查API KEY配置");
                } else {
                    // 服务从异常变为正常
                    handleServiceRecovery(serviceName);
                }
            } else if (!currentStatus) {
                // 服务持续异常
                handleServiceError(serviceName, "服务持续异常", "AI服务持续无法连接，请检查API KEY配置");
            }
            
            // 更新缓存
            lastStatusCache.put(serviceName, currentStatus);
        }
        
        log.info("API KEY状态检查完成");
    }
    
    /**
     * 检查单个服务的状态
     * @param service AI模型服务
     * @return 服务是否正常
     */
    private boolean checkServiceStatus(AiModelService service) {
        try {
            // 使用超时机制检查服务状态
            CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(service::isAvailable);
            return future.get(10, TimeUnit.SECONDS); // 10秒超时
        } catch (Exception e) {
            log.warn("检查服务 {} 状态时发生异常: {}", service.getModelName(), e.getMessage());
            return false;
        }
    }
    
    /**
     * 处理服务异常
     * @param serviceName 服务名称
     * @param errorType 异常类型
     * @param errorDescription 异常描述
     */
    private void handleServiceError(String serviceName, String errorType, String errorDescription) {
        // 增加异常计数
        int errorCount = errorCountMap.getOrDefault(serviceName, 0) + 1;
        errorCountMap.put(serviceName, errorCount);
        
        log.warn("服务 {} 出现异常，异常次数: {}", serviceName, errorCount);
        
        // 如果异常次数达到阈值，发送邮件提醒
        if (errorCount >= ERROR_THRESHOLD) {
            sendApiKeyAlertEmail(serviceName, errorType, errorDescription);
        }
    }
    
    /**
     * 处理服务恢复
     * @param serviceName 服务名称
     */
    private void handleServiceRecovery(String serviceName) {
        // 重置异常计数
        errorCountMap.put(serviceName, 0);
        
        log.info("服务 {} 已恢复正常", serviceName);
        
        // 发送恢复通知邮件
        sendServiceRecoveryEmail(serviceName);
    }
    
    /**
     * 发送API KEY异常提醒邮件
     * @param serviceName 服务名称
     * @param errorType 异常类型
     * @param errorDescription 异常描述
     */
    private void sendApiKeyAlertEmail(String serviceName, String errorType, String errorDescription) {
        try {
            // 获取管理员邮箱配置
            String adminEmail = appConfig.getEmail().getAdminEmail();
            if (adminEmail == null || adminEmail.isEmpty()) {
                log.warn("管理员邮箱未配置，无法发送API KEY异常提醒邮件");
                return;
            }
            
            // 构建邮件内容
            EmailDto.ApiKeyAlertEmailDto emailDto = new EmailDto.ApiKeyAlertEmailDto();
            emailDto.setToEmail(adminEmail);
            emailDto.setServiceName(serviceName);
            emailDto.setErrorType(errorType);
            emailDto.setErrorTime(LocalDateTime.now());
            emailDto.setErrorDescription(errorDescription);
            emailDto.setAdditionalInfo("请检查 " + serviceName + " 的API KEY配置和网络连接");
            
            // 发送邮件
            emailFacade.sendApiKeyAlertEmail(emailDto);
            
            log.info("已发送API KEY异常提醒邮件至: {}", adminEmail);
        } catch (Exception e) {
            log.error("发送API KEY异常提醒邮件失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 发送服务恢复通知邮件
     * @param serviceName 服务名称
     */
    private void sendServiceRecoveryEmail(String serviceName) {
        try {
            // 获取管理员邮箱配置
            String adminEmail = appConfig.getEmail().getAdminEmail();
            if (adminEmail == null || adminEmail.isEmpty()) {
                log.warn("管理员邮箱未配置，无法发送服务恢复通知邮件");
                return;
            }
            
            // 构建邮件内容
            EmailDto.ApiKeyAlertEmailDto emailDto = new EmailDto.ApiKeyAlertEmailDto();
            emailDto.setToEmail(adminEmail);
            emailDto.setServiceName(serviceName);
            emailDto.setErrorType("服务恢复");
            emailDto.setErrorTime(LocalDateTime.now());
            emailDto.setErrorDescription("AI服务已恢复正常连接");
            emailDto.setAdditionalInfo(serviceName + " 的API KEY配置正常，服务已恢复");
            
            // 发送邮件
            emailFacade.sendApiKeyAlertEmail(emailDto);
            
            log.info("已发送服务恢复通知邮件至: {}", adminEmail);
        } catch (Exception e) {
            log.error("发送服务恢复通知邮件失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 手动触发API KEY状态检查
     */
    public void manualCheckApiKeyStatus() {
        log.info("手动触发API KEY状态检查");
        checkApiKeyStatus();
    }
    
    /**
     * 获取服务状态信息
     * @return 服务状态信息
     */
    public Map<String, Object> getServiceStatusInfo() {
        Map<String, Object> statusInfo = new HashMap<>();
        
        for (AiModelService service : modelServices) {
            String serviceName = service.getModelName();
            Map<String, Object> serviceInfo = new HashMap<>();
            
            serviceInfo.put("currentStatus", service.isAvailable());
            serviceInfo.put("lastStatus", lastStatusCache.get(serviceName));
            serviceInfo.put("errorCount", errorCountMap.getOrDefault(serviceName, 0));
            
            statusInfo.put(serviceName, serviceInfo);
        }
        
        return statusInfo;
    }
}